﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cbs.Lucky.Events;
using Cbs.Lucky.Model;
using Cbs.Lucky.Services;
using Cbs.Lucky.Views;
using Newtonsoft.Json;
using NLog;
using OpenQA.Selenium.Chrome;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;

namespace Cbs.Lucky.ViewModels
{
    /// <summary>
    /// 数据列表
    /// </summary>
    public class DataListViewModel : BindableBase
    {
        private static Logger Logger = LogManager.GetCurrentClassLogger();
        public DataListViewModel(
            IDataItemService dataItemService,
            DataItemQueryParameter dataItemQueryParameter,
            IRegionManager regionManager,
            IEventAggregator eventAggregator)
        {
            DataItemService = dataItemService;
            _dataItemQueryParameter = dataItemQueryParameter;
            RegionManager = regionManager;
            _eventAggregator = eventAggregator;

            AutoGetDataCommand = new DelegateCommand(async () => await AutoGetDataAsync());
            RefreshDataCommand = new DelegateCommand(async () => await RefreshDataAsync());
            RefreshDataCommand.Execute();
            CreateCommand = new DelegateCommand(ShowCreate);
            ShowLoseQueryCommand = new DelegateCommand(ShowLoseQuery);

            _eventAggregator
                ?.GetEvent<CloseEvent>()
                ?.Subscribe(e =>
                {
                    switch (e.TypeName)
                    {
                        case "CreateOrUpdate":
                            RefreshDataCommand.Execute();
                            break;
                        default:
                            break;
                    }
                });
        }

        private void ShowLoseQuery()
        {
            Logger.Debug("CALL ShowLoseQuery");
            var reg = RegionManager
                ?.Regions[RegionNameEnum.RightFlyoutContentRegion.ToString()];
            var q = reg.Views.FirstOrDefault(f => f.GetType().Equals(typeof(LoseQuery)));
            reg.RemoveAll();
            if (q == null)
            {
                RegionManager.RegisterViewWithRegion(RegionNameEnum.RightFlyoutContentRegion, typeof(LoseQuery));
            }
            else
            {
                reg.Add(q);
            }
            _eventAggregator
                ?.GetEvent<ShowEvent>()
                ?.Publish(new ShowEventDetail
                {
                    Title = "遗漏查询",
                    TypeName = "LoseQuery"
                });
        }

        private void ShowCreate()
        {
            Logger.Debug("CALL CreateAsync");
            var reg = RegionManager
                ?.Regions[RegionNameEnum.RightFlyoutContentRegion.ToString()];
            var c = reg.Views.FirstOrDefault(f => f.GetType().Equals(typeof(CreateOrUpdate)));
            reg.RemoveAll();
            if (c == null)
            {
                RegionManager.RegisterViewWithRegion(RegionNameEnum.RightFlyoutContentRegion, typeof(CreateOrUpdate));
            }
            else
            {
                reg.Add(c);
            }
            _eventAggregator
                ?.GetEvent<ShowEvent>()
                ?.Publish(new ShowEventDetail
                {
                    Title = "添加",
                    TypeName = "CreateOrUpdate"
                });
        }

        private async Task<bool> RefreshDataAsync()
        {
            try
            {
                var result = await DataItemService?.Query(DataItemQueryParameter);
                //Logger.Debug(JsonConvert.SerializeObject(result));
                DataItems?.Clear();
                DataItems = new ObservableCollection<DataItem>(result);
            }
            catch (Exception ex)
            {
                Logger.Error($"RefreshData Message:{ex.Message},StackTrace:{ex.StackTrace}");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 自动获取数据
        /// </summary>
        private async Task AutoGetDataAsync()
        {
            try
            {
                Logger.Debug("CLICK AutoGetData");
                var mainJsScript = File.ReadAllText("Data/main.js");
                var options = new ChromeOptions();
                //options.AddArgument("--incognito");
                //options.AddArgument("headless");
                //options.AddArgument("disable-infobars");
                using (var driver = new ChromeDriver(AppDomain.CurrentDomain.BaseDirectory, options))
                {
                    driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1);
                    driver.Navigate().GoToUrl("https://chart.ydniu.com/trend/syx5sd/");
                    await Task.Delay(1000);
                    var btnQi200 = driver.FindElementByCssSelector("#filters > a:nth-child(3)");
                    btnQi200.Click();
                    await Task.Delay(2000);
                    var testData = "2,3,4,5,8";
                    var testArrStr = string.Join(",", testData
                        .Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
                        .Select(s => s.PadLeft(2, '0'))
                        .Select(s => $"'{s}'"));
                    dynamic jsResult = driver.ExecuteScript($@"{mainJsScript};
var data = parseData();
return {{
    Data : data
//,Result : find2(data,[{testArrStr}])
}};");
                    var data = jsResult["Data"];
                    //var result = jsResult["Result"];
                    //Logger.Debug($"JSResult:{JsonConvert.SerializeObject(jsResult)}");
                    //Logger.Debug($"Data:{JsonConvert.SerializeObject(data)}");
                    //Logger.Debug($"Result:{JsonConvert.SerializeObject(result)}");
                    IReadOnlyCollection<dynamic> ds = data;
                    var ordered = ds
                        .OrderByDescending(o => o[0])
                        .Select(s => new
                        {
                            Title = s[0],
                            Data = $"{s[1]},{s[2]},{s[3]},{s[4]},{s[5]}"
                        })
                        .ToList();
                    Logger.Debug($"Ordered:{JsonConvert.SerializeObject(ordered)}");
                    ordered.ForEach(e =>
                    {
                        var title = $"{e.Title}";
                        DataItemService?.Save(new DataItem
                        {
                            Id = title.ToInt32(),
                            Data = e.Data,
                            CreateTime = DateTime.Now,
                            CurrentDaySeqNum = title.Substring(title.Length - 2).ToInt32()
                        });
                    });
                    //IReadOnlyCollection<dynamic> rs = result;

                    //var orderResult = new List<dynamic>();
                    //rs.ForEach(rse =>
                    //{
                    //    var d = rse["data"];
                    //    var t = rse["title"];
                    //    var counter = 0;
                    //    foreach (var e in ordered)
                    //    {
                    //        if (e.Title == t)
                    //        {
                    //            break;
                    //        }
                    //        counter++;
                    //    }
                    //    orderResult.Add(new
                    //    {
                    //        Data = d,
                    //        Title = t,
                    //        Counter = counter,
                    //        Msg = $"遗漏 {counter} 期 , 上次是 {t} 期"
                    //    });
                    //});
                    //Logger.Debug($"OrderResult:{JsonConvert.SerializeObject(orderResult)}");
                    //var ods = orderResult
                    //    .OrderByDescending(o => o.Counter)
                    //    .ToList();
                    //Logger.Debug($"OrderResult重新排名:{JsonConvert.SerializeObject(ods, Formatting.Indented)}");
                    RefreshDataCommand.Execute();
                    driver.Close();
                    await Task.Delay(1000);
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"AutoGetDataAsync Message:{ex.Message},StackTrace:{ex.StackTrace}");
            }
        }

        public IDataItemService DataItemService { get; }
        public DelegateCommand AutoGetDataCommand { get; }
        public DelegateCommand RefreshDataCommand { get; }

        private ObservableCollection<DataItem> _dataItems;
        private DataItemQueryParameter _dataItemQueryParameter;

        public IRegionManager RegionManager { get; }

        private IEventAggregator _eventAggregator;

        public DataItemQueryParameter DataItemQueryParameter
        {
            get { return _dataItemQueryParameter; }
            set
            {
                SetProperty(ref _dataItemQueryParameter, value);
            }
        }

        /// <summary>
        /// 数据
        /// </summary>
        public ObservableCollection<DataItem> DataItems
        {
            get => _dataItems;
            set => SetProperty(ref _dataItems, value);
        }
        public DelegateCommand CreateCommand { get; }
        public DelegateCommand ShowLoseQueryCommand { get; }
    }

    /// <summary>
    /// DataItem查询条件
    /// </summary>
    public class DataItemQueryParameter : BindableBase
    {
        private int _limitNum = 100;

        public int LimitNum
        {
            get { return _limitNum; }
            set
            {
                SetProperty(ref _limitNum, value);
            }
        }
    }
}
